// =====================================================================
//
//  This file is part of the Microsoft Dynamics CRM SDK code samples.
//
//  Copyright (C) Microsoft Corporation.  All rights reserved.
//
//  This source code is intended only as a supplement to Microsoft
//  Development Tools and/or on-line documentation.  See these other
//  materials for detailed information regarding Microsoft code samples.
//
//  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
//
// =====================================================================
namespace Microsoft.Xrm.Sdk
{
	using System;
	using System.Diagnostics.CodeAnalysis;
	using System.Runtime.Serialization;
	using Microsoft.Xrm.Sdk.Temporary;

	/// <summary>
	/// Fault contract for IOrganizationService service contract.
	/// Use the OrganizationServiceFault contract to handle CRM specific errors in SDK client.
	/// </summary>
	[DataContract(Name = "BaseServiceFault", Namespace = XmlNamespaces.V5.Contracts)]
	[KnownType(typeof(DiscoveryServiceFault))]
	[KnownType(typeof(OrganizationServiceFault))]
	[Serializable]
	public abstract class BaseServiceFault : IExtensibleDataObject
	{
		/// <summary>
		/// Contains the error message included by CRM platform. This string is always in English.
		/// </summary>
		[DataMember]
		public string Message
		{
			get
			{
				return _message;
			}
			set
			{
				_message = value;
			}
		}

		/// <summary>
		/// Predefined error code returned by CRM. Refer to SDK helpers and documentation for list of codes.
		/// </summary>
		[DataMember]
		public int ErrorCode
		{
			get
			{
				return _errorCode;
			}
			set
			{
				_errorCode = value;
			}
		}

		/// <summary>
		/// Server time in UTC when the error occured.
		/// </summary>
		[DataMember]
		public DateTime Timestamp
		{
			get
			{
				return _timestamp;
			}
			set
			{
				_timestamp = value;
			}
		}

		/// <summary>
		/// Additional data returned from CRM. The contents of this property is error specific.
		/// </summary>
		[DataMember]
		public ErrorDetailCollection ErrorDetails
		{
			get
			{
				if (_details == null)
				{
					_details = new ErrorDetailCollection();
				}
				return _details;
			}
			set { _details = value; }
		}

		#region private members
		private DateTime _timestamp;
		private string _message;
		private int _errorCode;
		private ErrorDetailCollection _details;
		#endregion



		#region IExtensibleDataObject Implementation
		[NonSerialized]
		private ExtensionDataObject ExtensionDataObject;
		public ExtensionDataObject ExtensionData
		{
			get
			{
				return ExtensionDataObject;
			}
			set
			{
				ExtensionDataObject = value;
			}
		}
		#endregion IExtensibleDataObject Implementation
	}

	/// <summary>
	/// Fault contract for IDiscoveryService service contract.
	/// Use the DiscoveryServiceFault contract to handle CRM specific errors in SDK client.
	/// </summary>
	[DataContract(Name = "DiscoveryServiceFault", Namespace = XmlNamespaces.V5.Contracts)]
	[Serializable]
	public sealed partial class DiscoveryServiceFault : BaseServiceFault
	{
		public DiscoveryServiceFault()
			: base()
		{
		}

		/// <summary>
		/// Get the inner exception information that caused the fault
		/// </summary>
		[DataMember]
		public DiscoveryServiceFault InnerFault
		{
			get
			{
				return _innerFault;
			}
			set
			{
				_innerFault = value;
			}
		}

		#region private members
		private DiscoveryServiceFault _innerFault;
		#endregion
	}


	/// <summary>
	/// Fault contract for IOrganizationService service contract.
	/// Use the OrganizationServiceFault contract to handle CRM specific errors in SDK client.
	/// </summary>
	[DataContract(Name = "OrganizationServiceFault", Namespace = XmlNamespaces.V5.Contracts)]
	[Serializable]
	public sealed partial class OrganizationServiceFault : BaseServiceFault
	{
		public OrganizationServiceFault()
			: base()
		{
		}

		/// <summary>
		/// Diagnostic information added by custom plugins registered for the organization.
		/// </summary>
		[DataMember]
		public string TraceText
		{
			get
			{
				return _traceText;
			}
			set
			{
				_traceText = value;
			}
		}

		/// <summary>
		/// Get the inner exception information that caused the fault
		/// </summary>
		[DataMember]
		public OrganizationServiceFault InnerFault
		{
			get
			{
				return _innerFault;
			}
			set
			{
				_innerFault = value;
			}
		}

		#region private members
		private string _traceText;
		private OrganizationServiceFault _innerFault;
		#endregion
	}

	/// <summary>
	/// Makes a request to XRM services to perform a specific action.
	/// </summary>
	[SuppressMessage("Microsoft.Security", "CA9881:ClassesShouldBeSealed", Justification = "This class need to be instantiated by clients and be able to derive from it.")]
	[DataContract(Name = "OrganizationRequest", Namespace = XmlNamespaces.V5.Contracts)]
	[KnownType("RetrieveKnownTypes")]
	public class OrganizationRequest : IExtensibleDataObject
	{
		public static System.Collections.Generic.IEnumerable<Type> RetrieveKnownTypes()
		{
			return KnownTypesProvider.KnownOrganizationRequestResponseTypes.Values;
		}


		public OrganizationRequest()
		{
		}

		public OrganizationRequest(string requestName)
		{
			_messageName = requestName;
		}

		/// <summary>
		/// Name of the message represented by the request.
		/// </summary>
		[DataMember]
		public string RequestName
		{
			get { return _messageName; }
			set { _messageName = value; }
		}

		/// <summary>
		/// Indexer property for the Parameters collection
		/// </summary>
		/// <param name="parameterName">Name of the parameter</param>
		/// <returns>Parameter stored in the Parameters collection with the given parameter name</returns>
		public object this[string parameterName]
		{
			get
			{
				return this.Parameters[parameterName];
			}

			set
			{
				this.Parameters[parameterName] = value;
			}
		}

		/// <summary>
		/// Parameters for the request.
		/// </summary>
		[DataMember]
		public ParameterCollection Parameters
		{
			get
			{
				if (_propertyBag == null)
				{
					_propertyBag = new ParameterCollection();
				}
				return _propertyBag;
			}
			set { _propertyBag = value; }
		}

		/// <summary>
		/// Provides tracking mechanism for actions resulting from a request.
		/// </summary>
		[DataMember]
		public Guid? RequestId
		{
			get
			{
				return _requestId;
			}
			set
			{
				_requestId = value;
			}
		}

		#region private members
		private ParameterCollection _propertyBag;
		private string _messageName;
		private Guid? _requestId;
		#endregion


		#region IExtensibleDataObject Implementation
		private ExtensionDataObject ExtensionDataObject;
		public ExtensionDataObject ExtensionData
		{
			get
			{
				return ExtensionDataObject;
			}
			set
			{
				ExtensionDataObject = value;
			}
		}
		#endregion IExtensibleDataObject Implementation
	}

	/// <summary>
	/// Returns results from performing an action using a Request object.
	/// </summary>
	[SuppressMessage("Microsoft.Security", "CA9881:ClassesShouldBeSealed", Justification = "This class need to be instantiated by clients and be able to derive from it.")]
	[DataContract(Name = "OrganizationResponse", Namespace = XmlNamespaces.V5.Contracts)]
	[KnownType("RetrieveKnownTypes")]
	public class OrganizationResponse : IExtensibleDataObject
	{
		public static System.Collections.Generic.IEnumerable<Type> RetrieveKnownTypes()
		{
			return KnownTypesProvider.KnownOrganizationRequestResponseTypes.Values;
		}

		/// <summary>
		/// Name of the message represented by the request that was processed.
		/// </summary>
		[DataMember]
		public string ResponseName
		{
			get { return _messageName; }
			set { _messageName = value; }
		}

		/// <summary>
		/// Indexer property for the Results collection
		/// </summary>
		/// <param name="parameterName">Name of the parameter</param>
		/// <returns>Parameter stored in the Results collection with the given parameter name</returns>
		public object this[string parameterName]
		{
			get
			{
				return this.Results[parameterName];
			}

			set
			{
				this.Results[parameterName] = value;
			}
		}

		/// <summary>
		/// Results from processing a request.
		/// </summary>
		[DataMember]
		public ParameterCollection Results
		{
			get
			{
				if (_propertyBag == null)
				{
					_propertyBag = new ParameterCollection();
				}
				return _propertyBag;
			}
			set { _propertyBag = value; }
		}

		#region private members
		private ParameterCollection _propertyBag;
		private string _messageName;
		#endregion


		#region IExtensibleDataObject Implementation
		private ExtensionDataObject ExtensionDataObject;
		public ExtensionDataObject ExtensionData
		{
			get
			{
				return ExtensionDataObject;
			}
			set
			{
				ExtensionDataObject = value;
			}
		}
		#endregion IExtensibleDataObject Implementation
	}
}
